package cn.suimg.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


/**
 * 线程池工具类
 */
public final class ThreadPoolUtil {

    /**
     * Logger
     */
    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolUtil.class);

    /**
     * ThreadPool
     */
    private static final ExecutorService executorService = new ThreadPoolExecutor(1000, 2000, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()) {

        @Override
        public void beforeExecute(Thread t, Runnable r) {
            super.beforeExecute(t, r);
            logger.debug("===> 线程{}准备执行", ((Thread) r).getName());
        }

        @Override
        public void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
            logger.debug("===> 线程{}执行完成", ((Thread) r).getName());
        }

        @Override
        public void terminated() {
            super.terminated();
            logger.debug("===> 线程池退出");
        }

        @Override
        public void execute(Runnable command) {
            super.execute(wrap(command, clientTrace(), Thread.currentThread().getName()));
        }

        private Runnable wrap(Runnable command, Exception clientTrace, String name) {
            return new Thread() {

                @Override
                public void run() {
                    try {
                        command.run();
                    } catch (Exception e) {
                        logger.error("===》线程池中线程执行出现异常：", clientTrace);
                        throw e;
                    }
                }
            };
        }

        private Exception clientTrace() {
            return new Exception("client statck trace");
        }

    };

    /**
     * 添加一个线程到线程池当中
     * 为了整体安全和方便统一管理,所有线程务必使用此方法执行
     *
     * @param t
     */
    public static void submit(Runnable t) {
        executorService.submit(t);
    }

    /**
     * 获取当前激活的线程数
     *
     * @return
     */
    public static int getActiveCount() {
        return ((ThreadPoolExecutor) executorService).getActiveCount();
    }

    /**
     * 判断当前线程池是否已经满
     *
     * @return
     */
    public static boolean isFull() {
        ThreadPoolExecutor executorService = (ThreadPoolExecutor) ThreadPoolUtil.executorService;
        return executorService.getMaximumPoolSize() - executorService.getPoolSize() == 0;
    }

    /**
     * 获取线程池线程数量
     *
     * @return
     */
    public static int getPoolSize() {
        return ((ThreadPoolExecutor) executorService).getQueue().size();
    }
}
